﻿using System;
using System.Collections.Generic;

using NHibernate;
using Spring.Data.NHibernate.Generic.Support;

using Yawf.Core.Logs;

namespace Yawf.Data {
	public class NHibernatePersister : HibernateDaoSupport,IPersister{
		/// <summary>
		/// Executes a hql query and gets the first object found
		/// </summary>
		/// <param name="query">HQL Query to execute</param>
		/// <param name="parameters">Parameters to use, must be a Object[], 
		/// is decalred as object cause</param>
		/// <returns>Object found, null if query does not return anything</returns>
		public T FindOne<T>(String query,Object parameters){
			IList<T> hits;

			hits = HibernateTemplate.Find<T>(query,(Object[])parameters);
			if (hits != null && hits.Count > 0) {
				return hits[0];
			}

			return default(T);
		}									// FindOne

		/// <summary>
		/// Finds a list of objects by executing a HQL query
		/// </summary>
		/// <param name="query">HQL Query exeute</param>
		/// <param name="parameters">Parameters to set, must be a Object[]</param>
		/// <returns>A list of objects found</returns>
		public IList<T> FindList<T>(String query,Object parameters) {
			return FindList<T>(query,parameters,1,Int32.MaxValue);
		}									// FindList

		/// <summary>
		/// Finds a list of objects by executing a HQL query
		/// </summary>
		/// <param name="query">HQL Query exeute</param>
		/// <returns>A list of objects found</returns>
		public IList<T> FindList<T>(String query) {
			return FindList<T>(query,null,1,Int32.MaxValue);
		}									// FindList

		/// <summary>
		/// Finds a list of objects by executing a HQL query
		/// </summary>
		/// <param name="query">HQL Query exeute</param>
		/// <param name="parameters">Parameters to set, must be a Object[]</param>
		/// <param name="pageIndex">Page index to get, starts from 1</param>
		/// <param name="pageSize">Page size to return</param>
		/// <returns>A list of objects found</returns>
		public IList<T> FindList<T>(String query,Object parameters,int pageIndex,int pageSize) {
			try {
				return HibernateTemplate.ExecuteFind<T>(
					delegate(ISession session) {
						Object[] paramList;
						IQuery q;
						int i;

						// Create query
						paramList = (Object[])parameters;
						q = session.CreateQuery(query);
						if (pageIndex > 0) {
							q.SetFirstResult((pageIndex - 1) * pageSize);
						}
						q.SetMaxResults(pageSize);

						// Set parameters
						for (i = 0; paramList != null && i < paramList.Length; i++) {
							q.SetParameter(i,paramList[i]);
						}

						return q.List<T>();
					}
				);
			} catch (Exception e) {
				Log.ExceptionMessage(this.GetType(),"Error executing HQL Query in FindList",e);
			}

			return null;
		}									// FindList

		/// <summary>
		/// Deletes an Object from database
		/// </summary>
		/// <param name="query">Not used</param>
		/// <param name="o">Object to delete</param>
		public void Delete(String query,Object o) {
			HibernateTemplate.Delete(o);
		}									// Delete

		/// <summary>
		/// Updates an Object in database
		/// </summary>
		/// <param name="query">Not used</param>
		/// <param name="o">Object to update</param>
		public void Update(String query,Object o) {
			HibernateTemplate.SaveOrUpdate(o);
		}									// Update

		/// <summary>
		/// Inserts an Object into database
		/// </summary>
		/// <param name="query">Not used</param>
		/// <param name="o">Object to insert</param>
		public void Insert(String query,Object o) {
			HibernateTemplate.SaveOrUpdate(o);
		}									// Insert
	}
}
